package com.hengxinguotong.hxgtwygsp.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.hengxinguotong.hxgtwygsp.R;

import java.util.Arrays;

import dagger.android.ContributesAndroidInjector;

/**
 * TODO
 *
 * @author hjz
 * @version V1.0.0
 * @since 2019/3/27 14:43
 */

public class RingView extends View
{
    private int bgColor = Color.WHITE;

    private Paint circlePaint;
    private float outRadius;
    private SweepGradient sweepGradient;

    private Paint ringPaint;
    private float inRadius;
    private float inThickness;
    private RectF ringRectF;

    private Paint linePaint;

    private Paint ratioPaint;
    private boolean showRatio = false;
    private float ratioSize = 0f;
    private float ratioRadius = 0f;
    private float ratioWidth = 0f;
    private float ratioHeight = 0f;

    private Paint centerTextPaint;
    private float upTextSize;
    private float downTextSize;
    private String centerTextUp;
    private String centerTextDown;
    private float upDy;
    private float downDy;

    private int value;

    private int[] colors = {Color.parseColor("#D1B83B"),
            Color.parseColor("#00A0FF"),
            Color.parseColor("#7250FC"),
            Color.parseColor("#FE5660")};
    private float[] values = {0.1f, 0.2f, 0.3f, 0.4f};

    public RingView(Context context)
    {
        super(context);
        init(context, null);
    }

    public RingView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        init(context, attrs);
    }

    public RingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs)
    {
        value = getResources().getDimensionPixelSize(R.dimen.px_1);
        outRadius = value * 225f;
        inThickness = value * 45;
        inRadius = value * 195f;
        downDy = value * 40;

        if (attrs != null)
        {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RingView);
            outRadius = a.getDimension(R.styleable.RingView_rv_out_radius, outRadius);
            inThickness = a.getDimension(R.styleable.RingView_rv_in_thickness, inThickness);
            inRadius = a.getDimension(R.styleable.RingView_rv_in_radius, inRadius) - inThickness / 2;
            bgColor = a.getColor(R.styleable.RingView_rv_bg_color, Color.BLACK);
            showRatio = a.getBoolean(R.styleable.RingView_rv_show_ratio, false);
            a.recycle();
        }

        if (showRatio)
        {
            ratioPaint = new Paint();
            ratioSize = getResources().getDimensionPixelSize(R.dimen.sp_36);
            ratioPaint.setTextSize(ratioSize);
            ratioPaint.setTextAlign(Paint.Align.CENTER);
            ratioPaint.setAntiAlias(true);
            Rect rect = new Rect();
            ratioPaint.getTextBounds("100%", 0, 4, rect);
            ratioWidth = rect.width();
            ratioHeight = rect.height();
            ratioRadius = ratioWidth / 2 + outRadius;
        }

        circlePaint = new Paint();
        circlePaint.setStrokeWidth(value * 2);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setAntiAlias(true);
        updateCircleGradient();

        ringPaint = new Paint();
        ringPaint.setStrokeWidth(inThickness);
        ringPaint.setStyle(Paint.Style.STROKE);
        ringPaint.setAntiAlias(true);
        ringRectF = new RectF(-inRadius, -inRadius, inRadius, inRadius);

        linePaint = new Paint();
        linePaint.setStrokeWidth(value * 4);
        linePaint.setColor(bgColor);
        linePaint.setStyle(Paint.Style.STROKE);

        centerTextPaint = new Paint();
        upTextSize = getResources().getDimensionPixelSize(R.dimen.sp_48);
        downTextSize = getResources().getDimensionPixelSize(R.dimen.sp_24);
        centerTextPaint.setColor(Color.parseColor("#C8D8FF"));
        centerTextPaint.setTextAlign(Paint.Align.CENTER);
        centerTextPaint.setAntiAlias(true);
    }

    private void updateCircleGradient()
    {
        float[] positions = new float[values.length];
        int[] colors = new int[values.length];
        float valueSum = 0;
        for (int i = 0; i < values.length; i++)
        {
            positions[i] = valueSum + values[i] / 2;
            valueSum += values[i];
            colors[i] = this.colors != null && this.colors.length > i ? this.colors[i] : Color.BLACK;
        }
        sweepGradient = new SweepGradient(0f, 0f, colors, positions);
        circlePaint.setShader(sweepGradient);
    }

    public void setValues(float[] values)
    {
        if (values == null)
        {
            return;
        }
        this.values = new float[values.length];
        float valueSum = 0;
        for (float value : values)
        {
            valueSum += value;
        }
        for (int i = 0; i < values.length; i++)
        {
            this.values[i] = values[i] / valueSum;
        }
        updateCircleGradient();
        invalidate();
    }

    public void setColors(int[] colors)
    {
        if (values == null)
        {
            return;
        }
        this.colors = colors;
        updateCircleGradient();
        invalidate();
    }

    public void setCenterTextUp(String centerTextUp)
    {
        this.centerTextUp = centerTextUp;
        invalidate();
    }

    public void setCenterTextDown(String centerTextDown)
    {
        this.centerTextDown = centerTextDown;
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int defaultWidth = (int) ((outRadius + value * 2 + ratioWidth) * 2);
        setMeasuredDimension(measureDimension(defaultWidth, widthMeasureSpec), measureDimension(defaultWidth, heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        canvas.drawColor(bgColor);
        if (values != null)
        {
            canvas.translate(ratioWidth + outRadius, ratioWidth + outRadius);
            float sweepAngleSum = 0;
            float sweepAngle;
            double radians;
            int currentColor;
            for (int i = 0; i < values.length; i++)
            {
                currentColor = colors != null && colors.length > i ? colors[i] : Color.BLACK;
                ringPaint.setColor(currentColor);
                sweepAngle = values[i] * 360f;
                canvas.drawArc(ringRectF, sweepAngleSum - 90, sweepAngle, false, ringPaint);
                if (showRatio)
                {
                    ratioPaint.setColor(currentColor);
                    canvas.save();
                    radians = Math.toRadians(sweepAngleSum + sweepAngle / 2 - 90);
                    canvas.translate(ratioRadius * (float) Math.cos(radians), ratioRadius * (float) Math.sin(radians));
                    canvas.drawText((int) (values[i] * 100f) + "%", 0, ratioHeight / 2, ratioPaint);
                    canvas.restore();
                }
                sweepAngleSum += sweepAngle;
            }
            canvas.save();
            canvas.rotate(-90);
            canvas.drawCircle(0f, 0f, outRadius, circlePaint);
            for (int i = 0; i < values.length; i++)
            {
                sweepAngle = values[i] * 360f;
                canvas.rotate(sweepAngle);
                canvas.drawLine(0, 0, inRadius + value * 30, 0, linePaint);
            }
            canvas.restore();
            if (!TextUtils.isEmpty(centerTextUp))
            {
                centerTextPaint.setTextSize(upTextSize);
                canvas.drawText(centerTextUp, 0f, upDy, centerTextPaint);
            }
            if (!TextUtils.isEmpty(centerTextDown))
            {
                centerTextPaint.setTextSize(downTextSize);
                canvas.drawText(centerTextDown, 0f, downDy, centerTextPaint);
            }
        }

    }

    private int measureDimension(int defualtSize, int measureSpec)
    {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY)
        {
            result = specSize;
        } else if (specMode == MeasureSpec.AT_MOST)
        {
            result = Math.min(defualtSize, specSize);
        } else
        {
            result = defualtSize;
        }
        return result;
    }
}
